package com.hikvision.open.app.ui.local

import android.graphics.SurfaceTexture
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.hikvision.hatomplayer.DefaultHatomPlayer
import com.hikvision.hatomplayer.HatomPlayer
import com.hikvision.hatomplayer.PlayCallback
import com.hikvision.hatomplayer.PlayConfig
import com.hikvision.open.app.model.PlayResult
import com.hikvision.open.app.model.PlayStatus
import com.hikvision.open.app.utils.MyUtils
import com.hikvision.open.app.utils.Utils
import com.hikvision.open.app.utils.launch
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn

/**
 * <p> 本地播放界面的ViewModel </p>
 * @author 段自航 2021/7/27 10:46
 * @version V1.0
 */
class LocalPlayViewModel : ViewModel(), PlayCallback.PlayStatusCallback {


    private var hatomPlayer: HatomPlayer = DefaultHatomPlayer()

    /*播放状态，一开始默认为空闲状态*/
    private var playStatus = PlayStatus.IDLE

    /**
     * 播放结果
     */
    private val _previewResult = MutableLiveData<PlayResult>()
    val playResult: LiveData<PlayResult> = _previewResult

    /**
     * 进度监听
     */
    private val _playProgressResult = MutableLiveData<Int>()
    val playProgressResult: LiveData<Int> = _playProgressResult

    /*当前播放的进度*/
    var progress = 0

    /*录像总时长*/
    var fileTotalTime: Long = 1L

    /*触摸进度条开始标记*/
    var isSeekBarTouch = false
    var isPause = false
    var isSound = false


    fun startPlay(videoFilePath: String, surface: SurfaceTexture) {
        if (videoFilePath.isEmpty()) return
        hatomPlayer.setPlayStatusCallback(this)
        hatomPlayer.setSurfaceTexture(surface)
        val playInfo = PlayConfig()
        playInfo.privateData = true
        hatomPlayer.setPlayConfig(playInfo)
        hatomPlayer.playFile(videoFilePath)
    }

    fun stopPlay() {
        if (playStatus != PlayStatus.PLAYING) {
            return
        }
        hatomPlayer.stop()
    }

    fun playByProgress(progress: Double) {
        launch {
            flow {
                val result = hatomPlayer.setCurrentFrame(progress / 100)
                emit(result)
            }.flowOn(Dispatchers.IO).collectLatest {
                _playProgressResult.value = it
            }
        }
    }

    fun getTotalTime(): Long {
        if (playStatus != PlayStatus.PLAYING) {
            return -1
        }
        return hatomPlayer.totalTime
    }

    fun pause(): Boolean {
        if (playStatus != PlayStatus.PLAYING) {
            return false
        }
        hatomPlayer.pause()
        isPause = true
        return true
    }


    fun resume(): Boolean {
        if (playStatus != PlayStatus.PLAYING) {
            return false
        }
        hatomPlayer.resume()
        isPause = false
        return true
    }

    fun capture(): Boolean {
        if (playStatus != PlayStatus.PLAYING) {
            return false
        }
        val path = MyUtils.getCaptureImagePath(Utils.getApp())
        hatomPlayer.screenshot(path, "")
        return true
    }

    fun openAudio(isOpen: Boolean): Boolean {
        if (playStatus != PlayStatus.PLAYING) {
            return false
        }
        isSound = isOpen
        return hatomPlayer.enableAudio(isOpen) == 0
    }


    fun getPlayTime(): Long {
        if (playStatus != PlayStatus.PLAYING) {
            return -1
        }
        return hatomPlayer.playedTime
    }


    override fun onPlayerStatus(status: PlayCallback.Status, errorCode: String?) {
        when (status) {
            PlayCallback.Status.SUCCESS -> {
                if (playStatus != PlayStatus.PLAYING) {
                    //播放成功
                    playStatus = PlayStatus.PLAYING
                    _previewResult.postValue(PlayResult(status = PlayCallback.Status.SUCCESS))
                }
                if (progress > 0) {
                    playByProgress(progress.toDouble() / 100)
                }
            }
            PlayCallback.Status.FAILED -> {
                //播放失败，先关闭播放
                stopPlay()
                playStatus = PlayStatus.FAIL
                _previewResult.postValue(
                    PlayResult(
                        status = PlayCallback.Status.FAILED
                    )
                )
            }
            PlayCallback.Status.EXCEPTION -> {
                //发生异常，先关闭播放
                stopPlay()
                playStatus = PlayStatus.FAIL
                _previewResult.postValue(
                    PlayResult(
                        status = PlayCallback.Status.FAILED,
                    )
                )
            }
            PlayCallback.Status.FINISH -> {
                stopPlay()
                playStatus = PlayStatus.STOP
                _previewResult.postValue(
                    PlayResult(
                        status = PlayCallback.Status.FINISH
                    )
                )
            }
        }
    }

}